package com.chengh.nami.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chengh.nami.common.domain.pojo.SysRole;
import com.chengh.nami.common.exception.BizException;
import com.chengh.nami.common.request.PageQuery;
import com.chengh.nami.common.response.PageData;
import com.chengh.nami.common.utils.FileUtils;
import com.chengh.nami.common.utils.StringUtils;
import com.chengh.nami.system.domain.dto.RoleDto;
import com.chengh.nami.system.mapper.SysRoleMapper;
import com.chengh.nami.system.pojo.SysUserRole;
import com.chengh.nami.system.service.ISysRoleService;
import com.chengh.nami.system.service.ISysUserRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author chengh
 */
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    private final ISysUserRoleService sysUserRoleService;

    @Override
    public PageData<SysRole> getList(RoleDto roleDto, PageQuery pageQuery) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<SysRole>().like(StringUtils.isNotEmpty(roleDto.getRoleName()), SysRole::getRoleName, roleDto.getRoleName())
                .eq(StringUtils.isNotEmpty(roleDto.getRoleKey()), SysRole::getRoleKey, roleDto.getRoleKey())
                .ge(roleDto.getBeginTime() != null, SysRole::getCreateTime, roleDto.getBeginTime())
                .le(roleDto.getEndTime() != null, SysRole::getCreateTime, roleDto.getEndTime());
        Page<SysRole> sysRolePage = this.baseMapper.selectPage(pageQuery.build(), wrapper);
        return PageData.build(sysRolePage);
    }

    @Override
    public boolean addRole(SysRole sysRole) {
        List<SysRole> sysRoles = getSysRolesByNameOrKey(sysRole);
        if (!CollectionUtils.isEmpty(sysRoles)) {
            throw new BizException("权限名称或者权限字符重复！");
        }
        return this.save(sysRole);
    }

    private List<SysRole> getSysRolesByNameOrKey(SysRole sysRole) {
        // 需要判断角色的名字和角色的权限字符是否重复
        List<SysRole> sysRoles = this.baseMapper.selectList(new LambdaQueryWrapper<SysRole>()
                .or(wp -> wp.eq(SysRole::getRoleName, sysRole.getRoleName())
                        .or()
                        .eq(SysRole::getRoleKey, sysRole.getRoleKey()))
                .ne(sysRole.getId() != null, SysRole::getId, sysRole.getId()));
        return sysRoles;
    }

    @Override
    public boolean delRole(List<Long> ids) {
        // 需要先判断是否有用户用到该角色
        List<SysUserRole> infoByRoleIds = sysUserRoleService.getInfoByRoleIds(ids);
        if (CollectionUtils.isEmpty(infoByRoleIds)) {
            // 执行删除逻辑
            return this.removeByIds(ids);
        }
        List<Long> userIds = infoByRoleIds.stream().map(SysUserRole::getUserId).distinct().collect(Collectors.toList());
        throw new BizException("用户ID" + userIds + "有使用到该角色，请先取消用户角色信息。");
    }

    @Override
    public boolean editRole(SysRole sysRole) {
        List<SysRole> sysRoles = getSysRolesByNameOrKey(sysRole);
        if (!CollectionUtils.isEmpty(sysRoles)) {
            throw new BizException("权限名称或者权限字符重复！");
        }
        return this.updateById(sysRole);
    }

    @Override
    public void exportRoleExcle(HttpServletResponse response, RoleDto roleDto, PageQuery pageQuery) {
        PageData<SysRole> listPage = getList(roleDto, pageQuery);
        List<SysRole> list = listPage.getRecords();
        if(CollectionUtils.isEmpty(list)) {
            new BizException("查询到的结果为空");
        }
        List<Map<String, Object>> roleList = new ArrayList<>();
        for (SysRole sysRole : list) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("角色ID", sysRole.getId());
            map.put("角色名称", sysRole.getRoleName());
            map.put("角色标识", sysRole.getRoleKey());
            map.put("数据范围", sysRole.getDataScope());
            roleList.add(map);
        }
        try {
            FileUtils.downloadExcel(roleList, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
